package com.heima.search.service.impl;

import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.search.dtos.UserSearchDto;
import com.heima.search.service.ApUserSearchService;
import com.heima.search.service.ArticleSearchService;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.RangeQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @Description:
 * @Version: V1.0
 */
@Service
public class ArticleSearchServiceImpl implements ArticleSearchService {

    @Autowired
    RestHighLevelClient client;

    @Value("${file.oss.web-site}")
    private String webSite;

    @Autowired
    ApUserSearchService apUserSearchService;

    /**
     * 查询
     * @param dto
     * @return
     */
    @Override
    public ResponseResult search(UserSearchDto dto) {
        //1 校验参数
        if (dto == null || StringUtils.isBlank(dto.getSearchWords())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "抱歉，没有找到相关的文章");
        }

        //**** 异步调用记录历史
        apUserSearchService.insert(dto);



        //2 构建查询条件 bool
        SearchSourceBuilder sourceBuild = new SearchSourceBuilder();
        BoolQueryBuilder queryBuild = QueryBuilders.boolQuery();

        // 关键词 分词匹配
        MatchQueryBuilder titleMatchQuery = QueryBuilders
                .matchQuery("title", dto.getSearchWords())
                .analyzer("ik_smart");
        queryBuild.must(titleMatchQuery);

        // 发布时间 范围
        if (dto.getMinBehotTime() == null) {
            dto.setMinBehotTime(new Date());
        }
        RangeQueryBuilder publishTimeQuery = QueryBuilders.rangeQuery("publishTime").lte(dto.getMinBehotTime());
        queryBuild.filter(publishTimeQuery);

        // 分页
        if (dto.getPageSize() <= 0 || dto.getPageSize() > 50) {
            dto.setPageSize(10);
        }
        sourceBuild.from(0);
        sourceBuild.size(dto.getPageSize());

        // 发布时间倒序
        sourceBuild.sort("publishTime", SortOrder.DESC);

        // 高亮 三要素
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("title");
        highlightBuilder.preTags("<font style='color:red'>");
        highlightBuilder.postTags("</font>");
        sourceBuild.highlighter(highlightBuilder);


        SearchRequest searchRequest = new SearchRequest("app_info_article");
        sourceBuild.query(queryBuild);
        searchRequest.source(sourceBuild);



        //3 执行查询
        List<Map> resultList = new ArrayList<>();
        try {
            SearchResponse response = client.search(searchRequest, RequestOptions.DEFAULT);

            //4 解析结果并封装
            SearchHits hits = response.getHits();
            SearchHit[] searchHits = hits.getHits();

            for (SearchHit searchHit : searchHits) {

                Map<String, Object> map = searchHit.getSourceAsMap();

                // 保留原始文章标题
                map.put("o_title", map.get("title"));


                // 解析高亮的结果集
                HighlightField highlightField = searchHit.getHighlightFields().get("title");
                Text[] fragments = highlightField.getFragments();
                if (fragments != null && fragments.length > 0) {
                    String title = StringUtils.join(fragments);
                    map.put("title", title);
                }

                resultList.add(map);
            }


        } catch (IOException e) {
            e.printStackTrace();
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "抱歉，没有找到相关的文章");
        }

        //5 返回结果/ 图片封面
        ResponseResult result = ResponseResult.okResult(resultList);
        result.setHost(webSite);

        return result;
    }

}
